/**
 * 
 */
package algj.compilador.arvoresintatica.expressao;

import algj.compilador.GramaticaAlgJ;
import algj.compilador.arvoresintatica.ASTno;

/**
 * @author Laerte M. Rodrigues <laertemateus@gmail.com>
 * @version $Rev: 8 $
 */
public abstract class ASTexpressao extends ASTno {

	public ASTexpressao(GramaticaAlgJ p, int i) {
		super(p, i);
	}

	public ASTexpressao(int i) {
		super(i);
	}

	public TipoDado getTipo() throws Exception {
		switch (jjtGetNumChildren()) {
		case 1:
			return ((ASTexpressao) children[0]).getTipo();
		case 2:
			ASTexpressao filho1 = (ASTexpressao) children[0];
			ASTexpressao filho2 = (ASTexpressao) children[1];

			if (isNumerico(filho1.getTipo()) && isNumerico(filho2.getTipo())) {
				return filho1.getTipo() == TipoDado.REAL
						|| filho2.getTipo() == TipoDado.REAL ? TipoDado.REAL
						: TipoDado.INTEIRO;
			} else if (filho1.getTipo() != filho2.getTipo()) {
				throw new Exception(this + ": Tipos não correspondentes ("
						+ filho1.getTipo() + " e " + filho2.getTipo() + ")");
			}

			return filho1.getTipo();
		}

		throw new Exception(this + " nó da árvore sintática é um terminal!");
	}

	/**
	 * Verifica se o tipo de dado da expressão é numérico
	 */
	protected boolean isNumerico(TipoDado d) {
		return d == TipoDado.REAL || d == TipoDado.INTEIRO;
	}

	/* (non-Javadoc)
	 * @see algj.compilador.arvoresintatica.ASTno#validarSemantica()
	 */
	@Override
	public void validarSemantica() throws Exception {
		getTipo();
	}
}
